/** uupaa-imgsrc.js
 *
 * uupaa-imgsrc.js is Image support javascript library
 *  - uupaa.js spin-off project
 *
 * @author Takao Obara <uupaa.js@gmail.com>
 * @license uupaa-imgsrc.js is licensed under the terms and conditions of the MIT licence.
 * @version 0.1
 * @date 2008-12-06
 * @see <a href="http://code.google.com/p/uupaa-js/">uupaa.js Home(Google Code)</a>
 * @see <a href="http://code.google.com/p/uupaa-js-spinoff/">uupaa.js SpinOff Project Home(Google Code)</a>
 */

if (!uuClass.ImgSrc) {

/** Image Source
 *
 * @class
 */
uuClass.ImgSrc = uuClass();

// ImgSrc factory
uu.imgsrc = function(src) {
  return new uuClass.ImgSrc(src);
};

/** ImgSrc Dictionary
 *
 * @class Singleton
 */
uuClass.ImgSrcDictionary = uuClass.Singleton();

// --- local scope ------------------------------------------------------
(function() {
var _ua = uuClass.Detect, _dict;

// --- uuClass.ImgSrcDictionary methods ---
uuClass.ImgSrcDictionary.prototype = {
  // uuClass.ImgSrcDictionary.construct - create dictionary
  construct: function() {
    this._200 = { /* absURL: counter */ };
    this._404 = { /* absURL: counter */ };
  },

  // uuClass.ImgSrcDictionary.add - add URL
  add: function(absURL, code404) {
    if (code404) {
      this._404[absURL] ? ++this._404[absURL] : (this._404[absURL] = 1);
    } else {
      this._200[absURL] ? ++this._200[absURL] : (this._200[absURL] = 1);
    }
  },

  // uuClass.ImgSrcDictionary.in200 - Valid URL exists
  in200: function(absURL) {
    return absURL in this._200;
  },

  // uuClass.ImgSrcDictionary.get404 - get invalid URL array
  get404: function() {
    var rv = [], i;
    for (i in this._404) {
      rv.push(i);
    }
    return rv;
  }
};

uuClass.ImgSrc.prototype = {
  // uuClass.ImgSrc.construct - create instance, push image stack
  construct: function(src) {
    this._loading = 0;
    this._stack = [];
    this.push(src);
  },

  // uuClass.ImgSrc.push - push image stack
  push: function(src) {
    var i, iz, c;
    if (src !== void 0) {
      if (src instanceof uuClass.ImgSrc) { // stack copy
        for (i = 0, iz = src._stack.length; i < iz; ++i) {
          this._push(src._stack[i]); // clone
        }
      } else if (src instanceof Array) { // join array
        for (i = 0, iz = src.length; i < iz; ++i) {
          this._push(src[i]);
        }
      } else if (typeof src === "string") {
        if (/[;,]/.test(src)) { // "file1.ext;file2.ext" or "file1.ext,file2.ext"
          c = src.replace(/;/g, ",").split(",");
          for (i = 0, iz = c.length; i < iz; ++i) {
            this._push(c[i]);
          }
        } else { // "http://.../file.ext" or "file.ext"
          this._push(src);
        }
      }
    }
    return this;
  },
  _push: function(src) {
    src = uu.url.toAbsURL(src);
    if (!_dict.in200(src)) {
      ++this._loading;
      var me = this, img = new Image(), run = 0;

      img.onerror = function() {
        !run++ && (--me._loading, _dict.add(src, 1));
      };
      img.onabort = function() {
        !run++ && (--me._loading, _dict.add(src, 1));
      };
      img.onload  = function() {
        !run++ && (--me._loading, _dict.add(src, _ua.opera && !img.complete));
      };
      img.src = src;

      if (_ua.fx20) {
        (function() {
          if (!run) {
            if (img.complete && !img.width) {
              ++run;
              --me._loading;
              _dict.add(src, 1);
              return;
            }
            setTimeout(arguments.callee, 50); // peek 50ms
          }
        })();
      }
    }
    this._stack.push(src);
  },

  // uuClass.ImgSrc.pop - pop image stack
  pop: function() {
    return this._stack.pop() || "";
  },

  // uuClass.ImgSrc.clear - clear all image stack
  clear: function() {
    this._stack = [];
  },

  // uuClass.ImgSrc.size - get stack size
  size: function() {
    return this._stack.length;
  },

  // uuClass.ImgSrc.empty - is Empty stack(every false)
  empty: function() {
    return !this._stack.length;
  },

  // uuClass.ImgSrc.top - get top stack
  top: function() {
    return this.ref(this._stack.length - 1);
  },

  // uuClass.ImgSrc.bottom - get bottom stack
  bottom: function() {
    return this.ref(0);
  },

  // uuClass.ImgSrc.ref - refer to image stack
  ref: function(n /* = undefined(top stack) */) {
    return this._stack[this._ref(n)] || "";
  },
  _ref: function(n) {
    if (n !== void 0) { return n; }
    if (this._stack.length) { return this._stack.length - 1; }
    return 0; // empty stack
  },

  // uuClass.ImgSrc.loading - preloading image count
  loading: function() {
    return !!this._loading;
  },

  // uuClass.ImgSrc.forEach
  forEach: function(fn, me) {
    var v, i = 0, iz = this._stack.length;
    for(; i < iz; ++i) {
      v = this._stack[i];
      fn.call(me, v, i, this);
    }
    return this;
  },

  // uuClass.ImgSrc.toString - return ref()
  toString: function() {
    return this.ref();
  }
};

_dict = new uuClass.ImgSrcDictionary();

})(); // end (function())() scope

} // if (!uuClass.ImgSrc)

